/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.marcelo.agro.core.api;

import java.io.File;
import java.math.BigDecimal;
import java.util.List;
import java.util.Properties;
import org.marcelo.agro.constantes.IConstantes;
import org.marcelo.agro.entidades.*;


/**
 *
 * @author marcelo
 * Todas las demas interface heredan de esta interface
 */
public abstract interface IAccesoADatos<T> {
     public static String MENSAJE_ERROR_CONSULTA= IConstantes.MENSAJE_ERROR_CONSULTA;
    /**public static String MENSAJE_ERROR_CONSULTA="No se pudo conectar a la Base de datos";
     * Metodo para comprobar si el nombre de un campo es unico en la base de datos
     * cada implementacion busca la mejor forma de adaptar el objeto, aca muy basico busco 
     * solo por el nomnbre
     * @param nombre
     * @return 
     */
    public abstract Boolean esUnico(T object);
    
    /**
     * Metodo para determinar si el nombre de un objeto ya esta en uso
     * @param nombre 
     * @return 
     */
    public abstract Boolean esUnico(String nombre) ;
    
    /**
     * Metodo para encontrar un objeto que coincide exactamente con el nombre
     * Este metodo debe ser implementado en cada clase que herede de el
     * @param object
     * @return 
     */
    public abstract List<T> find(T object);
    
//    este metodo voy a pensarlo mejor de como se implementaria
//    public List<Class<T>> search(Class<T> clazz);
    
    public void saveOrUpdate(T object) throws Exception;
    
    public void saveOrUpdates(Object[] objects) throws Exception;
    
    public List<T> search(T object) ;
    
    
    /**
     * Este metodo puede ser implementado en cualquiera en la capa superior
     * @return 
     */
    public List<T> getAll();
    
    /**
     * Metodo para obtener la lista completa de Elementos
     * @return 
     */
    public List<?> getAll(Class clazz) ;
    
    /**
     * Metodo para obtener una lista de elementos limitando desde donde y hasta donde
     * @param inicio
     * @param fin
     * @return 
     */
    
    public List<T> getAll(Class clazz,Integer inicio, Integer fin) ;
    
    /**
     * Metodo para obtener la lista de objetos POJO's, pasando como parametro
     * una lista de ordenes para que, este metodo siempre ordena de manera ascendente
     * tengo que mejorarlo pra que ordene de forma descendente
     * @param campoOrdenes
     * @return 
     */
    public List<?> getAll(Class clazz , String... ordenarPorCampos) ;
    
    /**
     * Metodo para obtener una lista de elementos limitando desde donde y hasta donde
     * y seteando por cuales campos seran ordenados los resultados
     * @param clazz
     * @param inicio
     * @param fin
     * @param ordenarPorCampos 
     * @return 
     */
    public List<T> getAll(Class<T> clazz, Integer inicio, Integer fin, String... ordenarPorCampos) ;
    
//    /**
//     * Metodo para borrar un elemento
//     * @param object
//     * @throws Exception 
//     */
//    public void delete(T object) throws Exception;
    
    
    /**
     * Metodos de uso frecuente
     */
    /**
     * Retorna la lista de UnidadMedidaDosis
     * @return 
     */
    public List<UnidadMedidaDosis>      getUnidadMedidaDosis() ;
    /**
     * Retorna la lista de UnidadMedidaSuperficie, utilizado para los combos
     * @return 
     */
    public List<UnidadMedidaSuperficie> getUnidadesSuperficies();
    /**
     * Metodos para obtener la lista de datos para el combo de TiposActividades
     */
    public List<TipoActividad>          getTiposActividades();
    
    /**
     * Metodo para obtener la lista de TiposProductos utilizado en los combos
     * @return 
     */
    public List<TipoProducto>           getTiposProductos();
    
    /**
     * Este nombre esta mal el nombre de la tabla en la base de datos, pero no lo toco mas 
     * ni empedo por que va a acarrear muchisimos problemas
     */
    public List<TipoActividadXTipoProducto> getTipoProductosPorActividad();
   
    
    /**
     * Metodo para traer todos los tipos de productos filtrado por un tipo de 
     * actividad
     * @return Una lista de Tipo de Productos, puede retornar un arrayList vacio
     */
    public List<TipoProducto> getTiposProductos(TipoActividad ta);
    
    /**
     * 
     */
    
    public Integer getCount(Class<T> clazz);
    
    /**
     * Consultar la version de la base de datos
     * @return la version actual de la base de datos
     */
    public String getVersionBBDD();
    
    /**
     * La idea de este metodo es guardar valores de la tabla en csv
     * @return true si guardo, false en otro caso
     */
    public boolean saveTableToCSV(String tableName, File file) throws Exception ;
    
    /**
     * La idea es guardar los datos CSV en la tabla
     * @param tableName
     * @param file
     * @return
     * @throws Exception 
     */
    public boolean saveCsvToTable(String tableName, File file) throws Exception;
    
    /**
     * Metodo para guardar valores separados por un delimitador en una tabla
     * la configuracion del delimitador, el ENCODING y separador de caracteres puede ser pasado aqui
     * @param tableName
     * @param file
     * @param properties 
     * @return
     * @throws Exception 
     */
    public boolean saveCsvToTable(String tableName, File file, Properties properties ) throws Exception;
    
    /**
     * sirva para renovar los datos de un objeto
     * @param  object un objeto de Hibernate 
     * @throws Exception 
     */
    public void refreshObject(Object object) ;
    
    /**
     * Para conocer el total de superficie cultivable, que se ha registrado en el sistema
     * el Maximo valor posible es 
     * @return
     * @throws Exception 
     */
    public BigDecimal getTotalSuperficie() ;
    
    /**
     * Retorna el total de la superfice propia
     * @return 
     */
    public BigDecimal getTotalSuperficiePropia() ;
    
    /**
     * Retorna el total de la superfice Alquilada 
     * @return 
     */
    public BigDecimal getTotalSuperficieAlquilada() ;
    
    /**
     * Para determinar el total de superficie utilizada en un una campania
     * @param campana
     * @return
     */
    
    public BigDecimal getTotalSuperficie(Campanas campana) ;
    
    /**
     * MEtodo para borrar un elemento de la base de datos
     * @param object
     * @return verdadero si se borro falso en caso contrario
     */
    public Boolean delete(Object object) throws Exception;
}
